package Model;

import java.util.Random;

import javax.swing.JLabel;

import View.Display;


public class MonteCarloSingle implements Runnable{

	
	String CallPutFlag; Double S; Double X;Double T; Double r;Double b;Double v;int nSteps;int nSimulations;
	Double MonteCarloStandardOption=0.0;
	Display update;
	long start,end;
	
	 public MonteCarloSingle(String CallPutFlag, Double S, Double X,Double r, Double T,Double b,Double v,int nSteps,int nSimulations,Display display){
		 update=display;
		 this.CallPutFlag=CallPutFlag;
		 this.S=S;
		 this.X=X;
		 this.T=T;
		 this.r=r;
		 this.b=b;
		 this.v=v;
		 this.nSteps=nSteps;
		 this.nSimulations=nSimulations;
	 }
	 
	 //public Double calculate(String CallPutFlag, Double S, Double X,Double T, Double r,Double b,Double v,int nSteps,int nSimulations){
	public void calculate(){
		
		/*
		 * Function MonteCarloStandardOption (
	CallPutFlag As String, S As Double, X As Double,
	T As Double,
	r As Double, b As Double, v As Double,
	nSteps As Integer, nSimulations As Integer) As Double
	Dim dt As Double, St As Double
	Dim Sum As Double, Drift As Double, vSqrdt As Double
	Dim i As Integer, j As Integer, z As Integer
	dt = T / nSteps
	Drift = (b - v^2 / 2) * dt
	vSqrdt = v * Sqr(dt)
	If CallPutFlag=”c” Then
	z = 1
	ElseIf CallPutFlag=”p” Then
	z = -1
	EndIf
	For i = 1 to nSimulations
	St = S
	For j = 1 to nSteps
	St = St * Exp(Drift + vSqrdt * Application.No
	rmalInv(Rnd(),0,1))
	Next
	Sum = Sum + Max (z * (St – X), 0)
	Next
	MonteCarloStandardOption = Exp (-r * T) * (Sum /
	nSimulations)
	End Function 
		 */
		start = System.currentTimeMillis();
		 System.out.println(S+" "+  X+" "+ T+" "+ r+" "+ b+" "+ v+" "+ nSteps+" "+ nSimulations);
		 Double dt,St;
		 Double Sum=0.0, Drift,vSqrdt;
		 int i,j,z=0;
		 dt=T/nSteps;
		 Drift=(b- Math.pow(v, 2)/2)*dt;
		 vSqrdt=v*Math.sqrt(dt);
		 if(CallPutFlag.equals("c")){
			 z=1;
		 }else if(CallPutFlag.equals("p")){
			 z=-1;
		 }
		 for(i=1;i<=nSimulations;i++){
			 St=S;
			 //try { Thread.sleep (5); } catch (InterruptedException e) { }
			 if(i%(nSimulations/100)==0)update.setBar(i);
			 for(j=1;j<nSteps;j++){
				 Random rand=new Random();
				 St=St*Math.exp(Drift+vSqrdt*rand.nextGaussian());
			 }
			 Sum=Sum+Math.max(z*(St-X),0);
		 }
		 end = System.currentTimeMillis();
		 update.setExecutionSingle();
		 MonteCarloStandardOption=Math.exp(-r*T)*Sum/nSimulations;
		 update.setResultSingle(100000);
		 //JLabel newLabel=new JLabel();
		 //newLabel.setText(MonteCarloStandardOption+" "+Long.toString(getEnd() - getStart()) + " millis");
		 //update.addLabel(newLabel);
		 System.out.println(MonteCarloStandardOption);
		 
	 }

	public Double getMonteCarloStandardOption() {
		return MonteCarloStandardOption;
	}

	public void setMonteCarloStandardOption(Double monteCarloStandardOption) {
		MonteCarloStandardOption = monteCarloStandardOption;
	}

	@Override
	public void run() {
		//calculate(CallPutFlag, S, X,T, r,b,v,nSteps,nSimulations);

		start=System.currentTimeMillis();
		calculate();
	}

	public long getStart() {
		return start;
	}

	public void setStart(long start) {
		this.start = start;
	}

	public long getEnd() {
		return end;
	}

	public void setEnd(long end) {
		this.end = end;
	}
	 
	
	 
	 
	 
	 
	 
	 
}
